Modulation Plans#
Use for the couperin_concerts corpus only. Headings and function calls have been programatically generated for that
corpus.
%load_ext autoreload
%autoreload 2
import os
from typing import Literal
import re
from git import Repo
import ms3
import pandas as pd
import utils
from dimcat import plotting
from create_gantt import create_modulation_plan, get_phraseends
pd.set_option('display.max_rows', 1000)
pd.set_option('display.max_columns', 500)
RESULTS_PATH = os.path.abspath(os.path.join(utils.OUTPUT_FOLDER, "modulations"))
os.makedirs(RESULTS_PATH, exist_ok=True)
def save_figure_as(
fig, filename, formats=("png", "pdf"), directory=RESULTS_PATH, **kwargs
):
if formats is not None:
for fmt in formats:
plotting.write_image(fig, filename, directory, format=fmt, **kwargs)
else:
plotting.write_image(fig, filename, directory, **kwargs)
# CORPUS_PATH = os.path.abspath(os.path.join('..', '..')) # for running the notebook in the homepage deployment
# workflow
CORPUS_PATH = "~/all_subcorpora/couperin_concerts" # for running the notebook locally
utils.print_heading("Notebook settings")
print(f"CORPUS_PATH: {CORPUS_PATH!r}")
CORPUS_PATH = utils.resolve_dir(CORPUS_PATH)
Notebook settings
-----------------
CORPUS_PATH: '~/all_subcorpora/couperin_concerts'
repo = Repo(CORPUS_PATH)
utils.print_heading("Data and software versions")
print(f"Data repo '{utils.get_repo_name(repo)}' @ {repo.commit().hexsha[:7]}")
print("dimcat version [NOT USED]")
print(f"ms3 version {ms3.__version__}")
Data and software versions
--------------------------
Data repo 'couperin_concerts' @ 1946e01
dimcat version [NOT USED]
ms3 version 2.5.3
corpus_obj = ms3.Corpus(CORPUS_PATH)
corpus_obj.view.include('facet', 'expanded')
corpus_obj.parse_tsv()
corpus_obj
[default|all]
Corpus 'couperin_concerts'
--------------------------
Location: /home/laser/git/meta_repositories/all_subcorpora/couperin_concerts
View: This view is called 'default'. It
- excludes pieces that are not contained in the metadata,
- filters out file extensions requiring conversion (such as .xml),
- excludes review files and folders, and
- includes only facets containing 'expanded'.
All 84 pieces are listed in 'metadata.tsv':
expanded
detected parsed
c01n01_prelude 1 1
c01n02_allemande 1 1
c01n03_sarabande 1 1
c01n04_gavotte 1 1
c01n05_gigue 1 1
c01n06_menuet_en_trio 1 1
c02n01_prelude 1 1
c02n02_allemande_fuguee 1 1
c02n03_air_tendre 1 1
c02n04_air_contrefugue 1 1
c02n05_echos 1 1
c03n01_prelude 1 1
c03n02_allemande 1 1
c03n03_courante 1 1
c03n04_sarabande_grave 1 1
c03n05_gavotte 1 1
c03n06_musette_1 1 1
c03n07_musette_2 1 1
c03n08_chaconne_legere 1 1
c04n01_prelude 1 1
c04n02_allemande 1 1
c04n03_courante_francoise 1 1
c04n04_courante_a_litalienne 1 1
c04n05_sarabande 1 1
c04n06_rigaudon 1 1
c04n07_forlane 1 1
c05n01_prelude 1 1
c05n02_allemande 1 1
c05n03_sarabande 1 1
c05n04_gavote 1 1
c05n05_musete 1 1
c06n01_grave 1 1
c06n02_allemande 1 1
c06n03_sarabande 1 1
c06n04_air_diable 1 1
c06n05_siciliene 1 1
c07n01_grave 1 1
c07n02_allemande 1 1
c07n03_sarabande 1 1
c07n04_fuguete 1 1
c07n05_gavote 1 1
c07n06_siciliene 1 1
c08n01_ouverture 1 1
c08n02_ritournele 1 1
c08n03_air 1 1
c08n04_air_tendre 1 1
c08n05_air_leger 1 1
c08n06_Loure 1 1
c08n07_air 1 1
c08n08_sarabande 1 1
c08n09_air_leger 1 1
c08n10_air_lentement 1 1
c08n11_air_baccantes 1 1
c09n01_charme 1 1
c09n02_lenjouement 1 1
c09n03_graces 1 1
c09n04_Lejene 1 1
c09n05_vivacite 1 1
c09n06_Sarabande 1 1
c09n07_douceur 1 1
c09n08_caetera 1 1
c10n01_gravement 1 1
c10n02_air 1 1
c10n03_plainte 1 1
c10n04_tromba 1 1
c11n01_majestueusement 1 1
c11n02_allemande 1 1
c11n03_seconde_allemande 1 1
c11n04_courante 1 1
c11n05_seconde_courante 1 1
c11n06_sarabande 1 1
c11n07_gigue 1 1
c11n08_Rondeau 1 1
c14n01_gravement 1 1
c14n02_allemande 1 1
c14n03_sarabande 1 1
c14n04_fuguete 1 1
parnasse_01 1 1
parnasse_02 1 1
parnasse_03 1 1
parnasse_04 1 1
parnasse_05 1 1
parnasse_06 1 1
parnasse_07 1 1
11/12 facets are excluded from this view.
md = corpus_obj.metadata()
md.head()
| TimeSig | KeySig | last_mc | last_mn | length_qb | last_mc_unfolded | last_mn_unfolded | length_qb_unfolded | volta_mcs | all_notes_qb | n_onsets | n_onset_positions | guitar_chord_count | form_label_count | label_count | annotated_key | harmony_version | annotators | reviewers | composed_start | composed_end | composer | workTitle | movementNumber | movementTitle | workNumber | poet | lyricist | arranger | copyright | creationDate | mscVersion | platform | source | translator | title_text | subtitle_text | lyricist_text | composer_text | musescore | ms3_version | subdirectory | rel_path | has_drumset | ambitus | path | originalFormat | staff_1_instrument | staff_1_ambitus | staff_2_instrument | staff_2_ambitus | staff_3_instrument | staff_3_ambitus | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| piece | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| c01n01_prelude | {1: '4/4'} | {1: 1} | 25 | 23 | 98.0 | 25 | 23 | 98.0 | 219.00 | 386 | 251 | 0 | 0 | 94 | G | 2.3.0 | Eva-Maria Hamberger (2.1.0), Hanné Becker (2.3.0) | Johannes Menke (2.1.0) | 1722 | 1722 | François Couperin | Concert Royal no. 1 | 1 | Prélude | NaN | NaN | NaN | NaN | © Les Éditions Outremontaises, 2006 | 2019-10-09 | 3.02 | Linux | NaN | NaN | <font size="13.5"/><font face="SnellRoundhand ... | <font size="27"/><font face="SnellRoundhand Bo... | NaN | <font size="18"/><font face="SnellRoundhand Bo... | 3.6.2 | 2.5.4 | MS3 | MS3/c01n01_prelude.mscx | False | 36-84 (C2-C6) | MS3/c01n01_prelude.mscx | xml | Instrument 1 | 59-84 (B3-C6) | Instrument 1 | 36-57 (C2-A3) | NaN | NaN | |
| c01n02_allemande | {1: '4/4'} | {1: 1} | 20 | 18 | 72.0 | 40 | 36 | 144.0 | 168.50 | 346 | 207 | 0 | 0 | 78 | G | 2.3.0 | Eva-Maria Hamberger (2.1.0), Hanné Becker (2.3.0) | Johannes Menke (2.1.0) | 1722 | 1722 | François Couperin | Concert Royal no. 1 | 2 | Allemande | NaN | NaN | NaN | NaN | © Les Éditions Outremontaises, 2006 | 2019-10-09 | 3.02 | Linux | NaN | NaN | <font size="13.5"/><font face="SnellRoundhand ... | <font size="27"/><font face="SnellRoundhand Bo... | <font size="12"/>2 | <font size="18"/><font face="SnellRoundhand Bo... | 3.6.2 | 2.5.4 | MS3 | MS3/c01n02_allemande.mscx | False | 31-83 (G1-B5) | MS3/c01n02_allemande.mscx | xml | Instrument 1 | 59-83 (B3-B5) | Instrument 1 | 31-66 (G1-F#4) | NaN | NaN | |
| c01n03_sarabande | {1: '3/4'} | {1: -2} | 30 | 28 | 90.0 | 56 | 56 | 168.0 | [[[8], [9]], [[29], [30]]] | 237.75 | 291 | 159 | 0 | 0 | 68 | g | 2.3.0 | Eva-Maria Hamberger (2.1.0), Hanné Becker (2.3.0) | Johannes Menke (2.1.0) | 1722 | 1722 | François Couperin | Concert Royal no. 1 | 3 | Sarabande | NaN | NaN | NaN | NaN | © Les Éditions Outremontaises, 2006 | 2019-10-09 | 3.02 | Linux | NaN | NaN | <font size="13.5"/><font face="SnellRoundhand ... | <font size="27"/><font face="SnellRoundhand Bo... | NaN | <font size="18"/><font face="SnellRoundhand Bo... | 3.6.2 | 2.5.4 | MS3 | MS3/c01n03_sarabande.mscx | False | 31-81 (G1-A5) | MS3/c01n03_sarabande.mscx | xml | Instrument 1 | 58-81 (Bb3-A5) | Instrument 1 | 31-67 (G1-G4) | NaN | NaN |
| c01n04_gavotte | {1: '2/2'} | {1: -2} | 18 | 14 | 60.0 | 32 | 28 | 112.0 | [[[5], [6]], [[17], [18]]] | 135.00 | 195 | 113 | 0 | 0 | 54 | g | 2.3.0 | Eva-Maria Hamberger (2.1.0), Hanné Becker (2.3.0) | Johannes Menke (2.1.0) | 1722 | 1722 | François Couperin | Concert Royal no. 1 | 4 | Gavotte | NaN | NaN | NaN | NaN | © Les Éditions Outremontaises, 2006 | 2019-10-09 | 3.02 | Linux | NaN | NaN | <font size="13.5"/><font face="SnellRoundhand ... | <font size="27"/><font face="SnellRoundhand Bo... | <font size="12"/>4 | <font size="18"/><font face="SnellRoundhand Bo... | 3.6.2 | 2.5.4 | MS3 | MS3/c01n04_gavotte.mscx | False | 38-79 (D2-G5) | MS3/c01n04_gavotte.mscx | xml | Instrument 1 | 58-79 (Bb3-G5) | Instrument 1 | 38-57 (D2-A3) | NaN | NaN |
| c01n05_gigue | {1: '6/8'} | {1: 1} | 33 | 30 | 93.5 | 62 | 60 | 180.0 | [[[11], [12]], [[32], [33]]] | 194.00 | 389 | 215 | 0 | 0 | 139 | G | 2.3.0 | Eva-Maria Hamberger (2.1.0), Hanné Becker (2.3.0) | Johannes Menke (2.1.0) | 1722 | 1722 | François Couperin | Concert Royal no. 1 | 5 | Gigue | NaN | NaN | NaN | NaN | © Les Éditions Outremontaises, 2006 | 2019-10-09 | 3.02 | Linux | NaN | NaN | <font size="13.5"/><font face="SnellRoundhand ... | <font size="27"/><font face="SnellRoundhand Bo... | <font size="12"/>6 | <font size="18"/><font face="SnellRoundhand Bo... | 3.6.2 | 2.5.4 | MS3 | MS3/c01n05_gigue.mscx | False | 38-83 (D2-B5) | MS3/c01n05_gigue.mscx | xml | Instrument 1 | 59-83 (B3-B5) | Instrument 1 | 38-64 (D2-E4) | NaN | NaN |
def make_modulation_plans(
corpus_obj: ms3.Corpus,
yaxis: Literal['semitones', 'fifths', 'numeral'] = 'semitones',
regex = None
):
for fname, piece in corpus_obj.iter_pieces():
if regex is not None and not re.search(regex, fname):
continue
print(f"Creating modulation plan for {fname}...")
at = piece.expanded()
at = at[at.quarterbeats.notna() & (at.quarterbeats != "")]
metadata = md.loc[fname]
last_mn = metadata.last_mn
try:
globalkey = metadata.annotated_key
except Exception:
print('Global key is missing in the metadata.')
globalkey = '?'
data = ms3.make_gantt_data(at)
if len(data) == 0:
print(f"Could not create Gantt data for {fname}...")
continue
phrases = get_phraseends(at, "quarterbeats")
data.sort_values(yaxis, ascending=False, inplace=True)
fig = create_modulation_plan(data, title=f"{fname}", globalkey=globalkey, task_column=yaxis, phraseends=phrases)
fig.show()
c01#
make_modulation_plans(corpus_obj, regex='c01')
Creating modulation plan for c01n01_prelude...
Creating modulation plan for c01n02_allemande...
Creating modulation plan for c01n03_sarabande...
Creating modulation plan for c01n04_gavotte...
Creating modulation plan for c01n05_gigue...
Creating modulation plan for c01n06_menuet_en_trio...
c02#
make_modulation_plans(corpus_obj, regex='c02')
Creating modulation plan for c02n01_prelude...
Creating modulation plan for c02n02_allemande_fuguee...
Creating modulation plan for c02n03_air_tendre...
Creating modulation plan for c02n04_air_contrefugue...
Creating modulation plan for c02n05_echos...
c03#
make_modulation_plans(corpus_obj, regex='c03')
Creating modulation plan for c03n01_prelude...
Creating modulation plan for c03n02_allemande...
Creating modulation plan for c03n03_courante...
Creating modulation plan for c03n04_sarabande_grave...
Creating modulation plan for c03n05_gavotte...
Creating modulation plan for c03n06_musette_1...
Creating modulation plan for c03n07_musette_2...
Creating modulation plan for c03n08_chaconne_legere...
c04#
make_modulation_plans(corpus_obj, regex='c04')
Creating modulation plan for c04n01_prelude...
Creating modulation plan for c04n02_allemande...
Creating modulation plan for c04n03_courante_francoise...
Creating modulation plan for c04n04_courante_a_litalienne...
Creating modulation plan for c04n05_sarabande...
Creating modulation plan for c04n06_rigaudon...
Creating modulation plan for c04n07_forlane...
c05#
make_modulation_plans(corpus_obj, regex='c05')
Creating modulation plan for c05n01_prelude...
Creating modulation plan for c05n02_allemande...
Creating modulation plan for c05n03_sarabande...
Creating modulation plan for c05n04_gavote...
Creating modulation plan for c05n05_musete...
c06#
make_modulation_plans(corpus_obj, regex='c06')
Creating modulation plan for c06n01_grave...
Creating modulation plan for c06n02_allemande...
Creating modulation plan for c06n03_sarabande...
Creating modulation plan for c06n04_air_diable...
Creating modulation plan for c06n05_siciliene...
c07#
make_modulation_plans(corpus_obj, regex='c07')
Creating modulation plan for c07n01_grave...
Creating modulation plan for c07n02_allemande...
Creating modulation plan for c07n03_sarabande...
Creating modulation plan for c07n04_fuguete...
Creating modulation plan for c07n05_gavote...
Creating modulation plan for c07n06_siciliene...
c08#
make_modulation_plans(corpus_obj, regex='c08')
Creating modulation plan for c08n01_ouverture...
Creating modulation plan for c08n02_ritournele...
Creating modulation plan for c08n03_air...
Creating modulation plan for c08n04_air_tendre...
Creating modulation plan for c08n05_air_leger...
Creating modulation plan for c08n06_Loure...
Creating modulation plan for c08n07_air...
Creating modulation plan for c08n08_sarabande...
Creating modulation plan for c08n09_air_leger...
Creating modulation plan for c08n10_air_lentement...
Creating modulation plan for c08n11_air_baccantes...
c09#
make_modulation_plans(corpus_obj, regex='c09')
Creating modulation plan for c09n01_charme...
Creating modulation plan for c09n02_lenjouement...
Creating modulation plan for c09n03_graces...
Creating modulation plan for c09n04_Lejene...
Creating modulation plan for c09n05_vivacite...
Creating modulation plan for c09n06_Sarabande...
Creating modulation plan for c09n07_douceur...
Creating modulation plan for c09n08_caetera...
c10#
make_modulation_plans(corpus_obj, regex='c10')
Creating modulation plan for c10n01_gravement...
Creating modulation plan for c10n02_air...
Creating modulation plan for c10n03_plainte...
Creating modulation plan for c10n04_tromba...
c11#
make_modulation_plans(corpus_obj, regex='c11')
Creating modulation plan for c11n01_majestueusement...
Creating modulation plan for c11n02_allemande...
Creating modulation plan for c11n03_seconde_allemande...
Creating modulation plan for c11n04_courante...
Creating modulation plan for c11n05_seconde_courante...
Creating modulation plan for c11n06_sarabande...
Creating modulation plan for c11n07_gigue...
Creating modulation plan for c11n08_Rondeau...
c14#
make_modulation_plans(corpus_obj, regex='c14')
Creating modulation plan for c14n01_gravement...
Creating modulation plan for c14n02_allemande...
Creating modulation plan for c14n03_sarabande...
Creating modulation plan for c14n04_fuguete...
parnasse#
make_modulation_plans(corpus_obj, regex='parnasse')
Creating modulation plan for parnasse_01...
Creating modulation plan for parnasse_02...
Creating modulation plan for parnasse_03...
Creating modulation plan for parnasse_04...
Creating modulation plan for parnasse_05...
Creating modulation plan for parnasse_06...
Creating modulation plan for parnasse_07...